package cc.sunni.auto.task;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;


@Component
@Slf4j
public class AutoSign {
    @Value("${ttshitu.username}")
    private String username;
    @Value("${ttshitu.password}")
    private String password;

    /**
     * 每天8:00执行
     */
    @Async
    @Scheduled(cron = "0 4 17 * * ?")
    public void autoSign() throws IOException {
        String captcha = captcha(username, password);

        if (StrUtil.isBlank(captcha)) {
            // 最多重试3次
            for (int i = 0; i < 3; i++) {
                captcha = captcha(username, password);
                if (StrUtil.isNotBlank(captcha)) break;
            }
        }

        System.out.println("验证码=" + captcha);

    }

    /**
     * 获取验证码,并识别验证码
     */
    public static String captcha(String username, String password) throws IOException {
        // 图片验证码的地址
        HttpResponse response = HttpRequest.get("https://www.baacloud11.com/other/captcha.php").execute();
        byte[] imgData = response.bodyBytes();
        BufferedImage image = removeBackground(imgData);

        Map<String, Object> params = new HashMap<>();
        params.put("username", username);
        params.put("password", password);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImageIO.write(image, "png", out);
        byte[] data = out.toByteArray();
        String imageBase64 = new String(Base64.encodeBase64(data));
        params.put("image", imageBase64);
        // 统一识别接口
        String url = "http://api.ttshitu.com/predict";
        String body = HttpRequest.post(url)
                .header(Header.CONTENT_TYPE, "application/json;charset=UTF-8")
                .body(JSONUtil.toJsonStr(params))
                .execute().body();
        JSON json = JSONUtil.parse(body);
        Boolean success = json.getByPath("success", Boolean.class);
        String captcha = "";
        if (success) {
            captcha = json.getByPath("data.result", String.class);
        }
        return captcha;
    }

    /**
     * 根据颜色深浅与灰度值对比,将浅颜色置换成白色,深颜色置换成黑色
     * 通过颜色的深浅去除干扰因素
     * 通过灰度处理，将验证码中颜色较浅的点置换成白色，颜色较深的点置换成黑色。
     */
    public static BufferedImage removeBackground(byte[] imgData) throws IOException {
        int grayValue = 135;
        BufferedImage img = ImageIO.read(new ByteArrayInputStream(imgData));
        int width = img.getWidth();
        int height = img.getHeight();

        for (int x = 0; x < width; ++x) {
            for (int y = 0; y < height; ++y) {
                int p = img.getRGB(x, y);
                int a = (p >> 24) & 0xff;
                int r = (p >> 16) & 0xff;
                int g = (p >> 8) & 0xff;
                int b = p & 0xff;
                if (r * 0.299 + g * 0.578 + b * 0.114 >= grayValue) {
                    img.setRGB(x, y, Color.WHITE.getRGB());
                } else {
                    img.setRGB(x, y, Color.BLACK.getRGB());
                }
            }
        }
        return img;
    }
}
